package WsServer

import (
	"awesomeTask/commom/addrHelper"
	log2 "awesomeTask/system/log"
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"net"
	"net/http"
	"strconv"
	"sync"
)

const OnStart string = "on_tcp_start"
const OnMessage string = "on_tcp_message"
const OnConnect string = "on_tcp_connect"
const OnDisConnect string = "on_tcp_disconnect"
const OnError string = "on_tcp_err"
const OnClose string = "on_tcp_close"

type WsServer struct {
	listenPort  int
	debug       bool
	eventMap    map[string]interface{}
	listener    *net.TCPListener
	addr        *string
	upgrader    websocket.Upgrader
	connections sync.Map
	urls        sync.Map
}

func (server *WsServer) GetConnections() []*websocket.Conn {
	list := make([]*websocket.Conn, 0)
	server.connections.Range(func(key, value interface{}) bool {
		list = append(list, value.(*websocket.Conn))
		return true
	})
	return list
}
func (server *WsServer) Start(port int, url string, debug bool) {
	server.addr = addrHelper.BuildAddr("0.0.0.0", float64(port))
	log2.GetLogger().Info("启动ws服务:" + "0.0.0.0:" + strconv.Itoa(port))
	server.upgrader = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
	http.HandleFunc("/"+url, server.hander)
	//flag.Parse()
	log.SetFlags(0)
	if _, ok := server.eventMap[OnStart]; ok {
		fun := server.eventMap[OnStart].(func())
		if debug {
			fmt.Println("开启调试模式websocket:", "执行监听前的预处理")
		}
		go fun()
	}
	go http.ListenAndServe(*server.addr, nil)
}
func (server *WsServer) hander(w http.ResponseWriter, r *http.Request) {
	c, err := server.upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("upgrade:", err)
		log2.GetLogger().Error("upgrade:" + err.Error())
		return
	}
	server.connections.Store(c.RemoteAddr().String(), c)
	server.urls.Store(c.RemoteAddr().String(), r)
	if _, ok := server.eventMap[OnConnect]; ok {
		fun := server.eventMap[OnConnect].(func(con *websocket.Conn))
		go fun(c)
	}
	go server.handlerMsg(c)
}
func (server *WsServer) handlerMsg(con *websocket.Conn) {
	for {
		_, message, err := con.ReadMessage()
		if err != nil {
			log2.GetLogger().Error("read:" + err.Error())
			if _, ok := server.eventMap[OnClose]; ok {
				closeFun := server.eventMap[OnClose].(func(conn *websocket.Conn))
				if server.debug {
					fmt.Println("开启调试模式:", "客户端关闭连接=>"+con.RemoteAddr().String())
				}
				go closeFun(con)
			}
			break
		}
		if server.debug {
			fmt.Println("开启调试模式收到数据:" + string(message))
		}
		if _, ok := server.eventMap[OnMessage]; ok {
			messageFun := server.eventMap[OnMessage].(func(connection *websocket.Conn, message string))
			go messageFun(con, string(message))
		}
	}
}
func initServer(server *WsServer) {
	if server.eventMap == nil {
		server.eventMap = make(map[string]interface{})
	}
}
func (server *WsServer) GetRequest(con *websocket.Conn) *http.Request {
	re, _ := server.urls.Load(con.RemoteAddr().String())
	return re.(*http.Request)
}
func (server *WsServer) OnStart(fun func()) {
	initServer(server)
	server.eventMap[OnStart] = fun
}
func (server *WsServer) OnMessage(fun func(connection *websocket.Conn, message string)) {
	initServer(server)
	server.eventMap[OnMessage] = fun
}

func (server *WsServer) OnConnect(fun func(connection *websocket.Conn)) {
	initServer(server)
	server.eventMap[OnConnect] = fun
}

func (server *WsServer) OnDisConnect(fun func(connection *websocket.Conn)) {
	initServer(server)
	server.eventMap[OnDisConnect] = fun
}
func (server *WsServer) OnError(fun func(err error)) {
	initServer(server)
	server.eventMap[OnError] = fun
}
func (server *WsServer) OnClose(fun func(conn net.Conn)) {
	initServer(server)
	server.eventMap[OnClose] = fun
}
func (server *WsServer) Close() {
	initServer(server)
	server.listener.Close()
}
